package org.afox.formatting;

/*  
    This file is part of the Arctic Fox Code Tree (AFCT).
    Copyright 2002, Arctic Fox Computer Consulting Inc.

    AFCT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    AFCT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with AFCT; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/**
<P>   This class provides a single class method for formatting an object.
The actual formatting is performed by a format helper class which requires a 
specific implementation.

<P>If you were attempting to format the following class:

<P><PRE> org.afox.data.SomeClass </PRE> using the "html" format type you must create
the following class:

<P><PRE> org.afox.data.format.html.SomeClassFormatter</PRE> 
<P>This class must contain a method with the following syntax:
<pre>
	public String format(Object target, Object parameter)
</pre>

The parameter "target" is the object being formatted (it can be casted appropriately)
and the second parameter is data provided for the formatting (indentation level, for example).


@author <A HREF="mailto:schock@afox.org">Craig Schock</A>
@version 1.0

 */

public class Formatter
{

	/** Format the target using the type specified.  Throws a FormatException in the event of an error.
	 @return the formatted string */
	public static String formatChecked(Object target, String type) throws FormatException
	{
		return format(target, type, null);
	}

	/** Format the target using the type and parameter specified.  Throws a FormatException in the event of an error.
	 @return the formatted string */
	public static String formatChecked(Object target, String type, Object parameter) throws FormatException
	{
		String fullClass = target.getClass().getName();
		String packageName = fullClass.substring(0, fullClass.lastIndexOf("."));
		String name = fullClass.substring(fullClass.lastIndexOf(".")+1);

		try
		{
			return invokeFormat(Class.forName(packageName + ".format." + type + "." + name + "Formatter"), 
					    target, parameter);
		}
		catch (Exception x)
		{
			throw new FormatException(x.getClass().getName() + ":" + x.getMessage());
		}
	}


	/** Format the target using the type specified.  Returns empty string in the event of an error
	 @return the formatted string */
	public static String format(Object target, String type) 
	{
		try
		{
			return formatChecked(target, type, null);
		}
		catch(Exception x)
		{
			return "";
		}
	}

	/** Format the target using the type and parameter specified.  Returns empty string in the event of an error
	 @return the formatted string */
	public static String format(Object target, String type, Object parameter) 
	{
		try
		{
			return formatChecked(target, type, parameter);
		}
		catch(Exception x)
		{
			return "";
		}
	}
	

	private static String invokeFormat(Class aFormatClass, Object target, Object parameter) throws FormatException
	{
		Object[] parameters = {target, parameter};
		try
		{
			Class[] parameterTypes = {Class.forName("java.lang.Object"), Class.forName("java.lang.Object")};
			return (String)aFormatClass.getMethod("format", parameterTypes).invoke(aFormatClass.newInstance(),parameters);
		}
		catch(Exception x)
		{
			throw new FormatException(x.getMessage());
		}
	}
	       
	private static Class[] getClassArray(Object[] objects)
	{
		Class[] returnArray = new Class[objects.length];
		for(int i = 0; i < objects.length; i++)
		{
			returnArray[i] = objects[i].getClass();
		}
		return returnArray;
	}
}
